home *** CD-ROM | disk | FTP | other *** search
/ Packard Bell - Internet on a CD / internet on a cd.cdr / Internet / sites / Clementine_NASA / clemdsrc.hqx / huffman.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-27  |  4.4 KB  |  198 lines

  1. /*
  2.  *    THIS ROUTINE IS PART OF THE CLEMENTINE PDS FILE READER PROGRAM.
  3.  *    IT WAS WRITTEN BY ACT CORP. IN DIRECT SUPPORT TO THE 
  4.  *    CLEMENTINE (DSPSE) PROGRAM.
  5.  *
  6.  *    IF YOU FIND A PROBLEM OR MAKE ANY CHANGES TO THIS CODE PLEASE CONTACT
  7.  *    Dr. Erick Malaret at ACT Corp. 
  8.  *            tel: (703) 742-0294
  9.  *                 (703) 683-7431
  10.  *                       email:    nrlvax.nrl.navy.mil
  11.  *    
  12.  *
  13.  */
  14. #include <stdio.h>
  15. #include "jpeg_c.h"
  16. #include "pds.h"
  17.  
  18. #define ZRL 240
  19. #define EOB 0
  20.  
  21. void inithuffcode();
  22. void genhuffsize(char *, short *, short *);
  23. void genhuffcode(short *, char *);
  24. void genehuf(short *, short *, short *, char *, char *, short);
  25. void gendectbls(short *, short *, short *, short *, short *);
  26.  
  27.  
  28. short    dcbits[16], acbits[16];
  29. char    dchuffval[12], achuffval[162];
  30.  
  31. short    dcehufco[16];
  32. short    dcehufsi[16];
  33. short    dcmincode[16];
  34. short    dcmaxcode[16];
  35. short    dcvalptr[16];
  36.  
  37. short    acehufco[256];
  38. short    acehufsi[256];
  39. short    acmincode[16];
  40. short    acmaxcode[16];
  41. short    acvalptr[16];
  42.  
  43. /******************* Initialization of Huffman tables ********************/
  44. void inithuffcode()
  45. {
  46.     char    dchuffsize[13], achuffsize[163];
  47.     short   dchuffcode[12], achuffcode[162];
  48.     short   dclastk, aclastk, i;
  49.  
  50.     /* generate dc Huffman codes */
  51.     genhuffsize(dchuffsize,dcbits,&dclastk);
  52.     genhuffcode(dchuffcode,dchuffsize);
  53.     fprintf(qparm,"dc huffman tables:\n");
  54.     fprintf(qparm,"(symbol length  code)\n");
  55.     genehuf(dcehufco,dcehufsi,dchuffcode,dchuffsize,dchuffval,dclastk);
  56.  
  57.     /* generate ac Huffman codes */
  58.     genhuffsize(achuffsize,acbits,&aclastk);
  59.     genhuffcode(achuffcode,achuffsize);
  60.     fprintf(qparm,"ac huffman tables:\n");
  61.     fprintf(qparm,"(symbol length  code)\n");
  62.     genehuf(acehufco,acehufsi,achuffcode,achuffsize,achuffval,aclastk);
  63.  
  64.     /* generate decoding tables */
  65.     gendectbls(dcmincode,dcmaxcode,dcvalptr,dchuffcode,dcbits);
  66.     gendectbls(acmincode,acmaxcode,acvalptr,achuffcode,acbits);
  67. }
  68.  
  69. void genhuffsize(char *huffsize, short *bits, short *lastk)
  70. {
  71.     short     i = 0,j = 1,k = 0;
  72.  
  73.     while ( i < 16 )
  74.         if ( j > bits[i] ) {
  75.             i++;
  76.             j = 1;
  77.         } else {
  78.             huffsize[k] = i+1;
  79.             k++;
  80.             j++;
  81.         }
  82.     huffsize[k] = 0;
  83.     *lastk = k;
  84. }
  85.  
  86. void genhuffcode(short *huffcode, char *huffsize)
  87. {
  88.     short   code, k;
  89.     char    si;
  90.  
  91.     k = code = 0;
  92.     si = huffsize[0];
  93.  
  94.     while ( huffsize[k] ) {
  95.         if ( huffsize[k] == si ) {
  96.             huffcode[k] = code;
  97.             code++; k++;
  98.         } else {
  99.             code <<= 1;
  100.             si++;
  101.         }
  102.     }
  103. }
  104.  
  105. void genehuf(short *ehufco, short *ehufsi, short *huffcode, char *huffsize,
  106.              char *huffvalue, short lastk)
  107. {
  108.     short   k;
  109.     short   value;
  110.  
  111.     for (k=0; k < lastk; k++) {
  112.         value = ((short)huffvalue[k])&0x00ff;
  113.         ehufco[value] = huffcode[k];
  114.         ehufsi[value] = huffsize[k];
  115.         fprintf(qparm,"%#.2x\t%d\t%#x\n",
  116.                 huffvalue[k]&0x00ff,
  117.                 ehufsi[value],
  118.                                 ehufco[value] );
  119.     }
  120. }
  121.  
  122. void gendectbls(short *mincode, short *maxcode, short *valptr, short *huffcode, short *bits)
  123. {
  124.     short     k, l;
  125.  
  126.     l = k = 0;
  127.  
  128.     while ( l < 16 ) {
  129.         if ( bits[l] ) {
  130.             valptr[l] = k;
  131.             mincode[l] = huffcode[k];
  132.             maxcode[l] = huffcode[k + bits[l] -1];
  133.             k += bits[l];
  134.         } else
  135.             maxcode[l] = -1;
  136.         l++;
  137.     }
  138. }
  139.  
  140.  
  141. /************************** Decoding Section *****************************/
  142.  
  143. unsigned short mask[] = {0x0000,
  144. 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
  145. 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
  146.  
  147. short   code;
  148.  
  149. void decode(short *u, BitStream *ibs)
  150. {
  151.     short     symbol, coeff, i, run, cat, j, l;
  152.  
  153.         /* get dc coefficient */
  154.     l = 0;
  155.     code = BitStream_read(ibs,1);
  156.     while ( code > dcmaxcode[l] ) {
  157.         code = (short)(code << 1) | BitStream_read(ibs,1);
  158.         l++;
  159.     }
  160.     symbol = (dchuffval[dcvalptr[l] + code - dcmincode[l]]) & 0x00ff;
  161.     if ( symbol ) {
  162.         coeff = BitStream_read(ibs,symbol);
  163.         if ( coeff & mask[symbol] )
  164.             u[0] = coeff;
  165.         else
  166.             u[0] = ((0xffff << symbol) | coeff) + 1;
  167.     } else
  168.         u[0] = 0;
  169.  
  170.     /* get ac coefficients */
  171.     i = 1;
  172.     while ( i < 64 ) {
  173.         l = 0;
  174.         code = BitStream_read(ibs,1);
  175.         while ( code > acmaxcode[l] ) {
  176.             code = (short)(code << 1) | BitStream_read(ibs,1);
  177.             l++;
  178.         }
  179.         symbol = (achuffval[acvalptr[l] + code - acmincode[l]]) & 0x00ff;
  180.  
  181.         if ( symbol == ZRL ) {
  182.             for (j=0; j < 16; j++) u[i++] = 0;
  183.         } else if ( symbol == EOB ) {
  184.             for (j=i; j < 64; j++) u[i++] = 0;
  185.         } else {
  186.             run = (symbol >> 4) & 0x000f;
  187.             cat = symbol&0x000f;
  188.             while ( run-- ) u[i++] = 0;
  189.  
  190.             coeff = BitStream_read(ibs,cat);
  191.             if ( coeff & mask[cat] )
  192.                 u[i++] = coeff;
  193.             else
  194.                 u[i++] = ((0xffff << cat) | coeff) + 1;
  195.         }
  196.     }
  197. }
  198.